package myJs.cps.myTable

import japgolly.scalajs.react.React.Fragment
import japgolly.scalajs.react._
import japgolly.scalajs.react.vdom.all._
import myJs.Utils._
import myJs.cps.BootstrapTableCp.Column
import myJs.myPkg.i18n._
import myJs.myPkg.jquery.$
import myJs.tool.Pojo._
import myJs.tool.Tool._
import org.scalajs.dom.document
import org.scalajs.dom.html.Button

import scala.collection.immutable.SeqMap
import scala.scalajs.js

/** Created by yz on 15/9/2023
  */
object FilterButtonCp {

  case class Props(
      column: Column,
      sortField: String,
      sortFieldChange: String => Callback,
      order: String,
      orderChange: String => Callback,
      menuShow: Boolean,
      menuShowChange: Boolean => Callback,
      menuField: String,
      menuFieldChange: String => Callback,
      tmpSearchMap: SeqMap[String, SearchData],
      tmpSearchMapChange: (SeqMap[String, SearchData] => SeqMap[String, SearchData]) => Callback,
      confirmFilter: String => Callback
  ) {
    @inline def render: VdomElement = {
      Component(this)
    }
  }

  val Component = ScalaFnComponent[Props] { props =>
    val js.Tuple3(t, i18n, _) = ReactI18next.useTranslation()

    object FTool {

      def menuShowF(curField: String)(e: ReactEventFromInput) = {
        val buttonJq = $(e.target.asInstanceOf[Button])
        val yTotalLeft = buttonJq.offset().left
        val width = 210
        val pageWidth = document.body.clientWidth
        val trueYLeft = if (yTotalLeft + width > pageWidth) pageWidth - 220 - 6 - yTotalLeft else 0
        val ulJq = buttonJq.parent().find("ul")
        ulJq.css("left", s"${trueYLeft}px")
        props.menuShowChange(true) >>
          props.menuFieldChange(curField)
      }

      def execSort(curSortField: String, curOrder: String) = {
        props.sortFieldChange(curSortField) >>
          props.orderChange(curOrder) >>
          props.menuShowChange(false)
      }

      def startDateChange(curField: String) = (v: String) => {
        props.tmpSearchMapChange { map =>
          map.updatedWith(curField) { op =>
            op.map { searchData =>
              searchData.asInstanceOf[DateSearchData].copy(startDate = v)
            }
          }
        }
      }

      def endDateChange(curField: String) = (v: String) => {
        props.tmpSearchMapChange { map =>
          map.updatedWith(curField) { op =>
            op.map { searchData =>
              searchData.asInstanceOf[DateSearchData].copy(endDate = v)
            }
          }
        }
      }

      def searchTypeChange(curField: String) = (v: String) => {
        props.tmpSearchMapChange { map =>
          map.updatedWith(curField) { op =>
            op.map { searchData =>
              searchData.asInstanceOf[TextSearchData].copy(searchType = v)
            }
          }
        }
      }

      def textChange(curField: String) = (v: String) => {
        props.tmpSearchMapChange { map =>
          map.updatedWith(curField) { op =>
            op.map { x =>
              x.asInstanceOf[TextSearchData].copy(text = v)
            }
          }
        }
      }

      def minChange(curField: String) = (v: String) => {
        props.tmpSearchMapChange { map =>
          map.updatedWith(curField) { op =>
            op.map { searchData =>
              searchData.asInstanceOf[NumericSearchData].copy(min = v)
            }
          }
        }
      }

      def maxChange(curField: String) = (v: String) => {
        props.tmpSearchMapChange { map =>
          map.updatedWith(curField) { op =>
            op.map { searchData =>
              searchData.asInstanceOf[NumericSearchData].copy(max = v)
            }
          }
        }
      }

      def valuesChange(curField: String) = (v: List[String]) => {
        props.tmpSearchMapChange { map =>
          map.updatedWith(curField) { op =>
            op.map { searchData =>
              searchData.asInstanceOf[CheckboxSearchData].copy(values = v)
            }
          }
        }
      }

      def hideMenu = {
        props.menuShowChange(false)
      }

    }

    val column = props.column
    val sortField = props.sortField
    val order = props.order
    val menuShow = props.menuShow
    val menuField = props.menuField
    val tmpSearchMap = props.tmpSearchMap
    if (column.operable && tmpSearchMap.isDefinedAt(column.field)) {
      val isAscActive = (column.field == sortField && order == "asc")
      val isDescActive = (column.field == sortField && order == "desc")
      val sortFa = if (isAscActive) {
        "fa-long-arrow-up"
      } else if (isDescActive) {
        "fa-long-arrow-down"
      } else ""

      val ulDisplay = if (menuShow && menuField == column.field) "block" else "none"

      val searchData = tmpSearchMap(column.field)
      val isNumeric = searchData match {
        case NumericSearchData(min, max, kind) => true
        case _ => false
      }

      div(
        float.right,
        position.relative,
        marginLeft := "2px",
        className := "myFilterButton",
        button(
          className := "btn btn-default dropdown-toggle myButton",
          dataToggle := "dropdown",
          onClick ==> FTool.menuShowF(column.field),
          span(className := "caret"),
          i(className := s"fa ${sortFa}")
        ),
        ul(
          marginTop := 0.px,
          background := "#F8F8F8",
          border := "1px solid #c5c5c5",
          borderRadius := 0.px,
          fontWeight := "400",
          paddingTop := 0.px,
          paddingBottom := 0.px,
          width := 212.px,
          boxShadow := "1px 2px 3px rgba(0, 0, 0, .5)",
          display := ulDisplay,
          className := "dropdown-menu menuContent filterContent",
          form(
            className := "form-horizontal myForm",
            AscLiCp
              .Props(onClickF = FTool.execSort(column.field, "asc"), isActive = isAscActive, isNumeric = isNumeric)
              .render,
            DescLiCp
              .Props(onClickF = FTool.execSort(column.field, "desc"), isActive = isDescActive, isNumeric = isNumeric)
              .render,
            if(searchData==OnlySortData){
              EmptyVdom
            }else{
              Fragment(
                li(className := "myDivider"),
                searchData match {
                  case DateSearchData(startDate, endDate) =>
                    DateSearchLiCp
                      .Props(
                        startDate = startDate,
                        startDateChange = FTool.startDateChange(column.field),
                        endDate = endDate,
                        endDateChange = FTool.endDateChange(column.field)
                      )
                      .render
                  case TextSearchData(searchType, text) =>
                    TextSearchLiCp
                      .Props(
                        searchType = searchType,
                        searchTypeChange = FTool.searchTypeChange(column.field),
                        text = text,
                        textChange = FTool.textChange(column.field)
                      )
                      .render
                  case NumericSearchData(min, max, kind) =>
                    NumericSearchLiCp.Props(
                      min = min,
                      minChange = FTool.minChange(column.field),
                      max = max,
                      maxChange = FTool.maxChange(column.field)
                    ).render
                  case CheckboxSearchData(values) =>
                    CheckboxSearchLiCp
                      .Props(
                        values = values,
                        valuesChange = FTool.valuesChange(column.field),
                        optionMap = column.optionMap
                      )
                      .render
                },
                div(
                  marginTop:=10.px,
                  className := "modal-footer bg-info",
                  button(className := "btn btn-sm blue", onClick --> props.confirmFilter(column.field),
                    s"${t("confirm")}"),
                  button(
                    `type` := "button",
                    className := "btn btn-default myHide",
                    s"${t("close")}",
                    onClick --> FTool.hideMenu
                  )
                )
              )
            }


          ),
        )
      )

    } else EmptyVdom

  }

}
